package com.ruirenyun.util.common;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.awt.image.BufferedImage;
import java.io.File;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 公共工具类
 */
public class CommonUtil {
    private static final Logger logger = LoggerFactory.getLogger(CommonUtil.class);
    private static final int LEN2 = 0;
    private static final String CHARSET = "utf-8";
    public static final String ID_CARD_REGEX = "^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|31)|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}([0-9]|x|X)$";
    public static final String PHONE_REGEX = "^[1]([1-9])[0-9]{9}$";

    /**
     * 获取UUID主键
     *
     * @return
     */
    public static String uuid() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * 修改 map 中空字符串为 null，其余字符串去掉前后空格
     *
     * @param map
     */
    public static void changeEmptyValToNull(Map<String, Object> map) {
        if (null != map && !map.isEmpty()) {
            for (String key : map.keySet()) {
                if (map.get(key) instanceof String) {
                    if (isBlank((String) map.get(key))) {
                        map.put(key, null);
                    } else {
                        map.put(key, map.get(key).toString().trim());
                    }
                }
            }
        }
    }

    /**
     * 设置对象中空字符串为null
     *
     * @param source
     * @param <T>
     * @return
     */
    public static <T> T setNullValue(T source) {
        if (null == source) {
            return source;
        }

        Field[] fields = source.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.getGenericType().toString().equals(
                    "class java.lang.String")) {
                field.setAccessible(true);
                try {
                    Object obj = field.get(source);
                    if (isBlank((String) obj)) {
                        field.set(source, null);
                    } else if (obj != null) {
                        field.set(source, obj.toString().trim());
                    }
                } catch (IllegalAccessException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }

        if (null != source.getClass().getSuperclass()) {
            Field[] fields2 = source.getClass().getSuperclass().getDeclaredFields();
            for (Field field : fields2) {
                if (field.getGenericType().toString().equals(
                        "class java.lang.String")) {
                    field.setAccessible(true);
                    try {
                        Object obj = field.get(source);
                        if (isBlank((String) obj)) {
                            field.set(source, null);
                        } else if (obj != null) {
                            field.set(source, obj.toString().trim());
                        }
                    } catch (IllegalAccessException e) {
                        logger.error(e.getMessage(), e);
                    }
                }
            }
        }
        return source;
    }

    /**
     * 判断是否是空字符串 null和"" 都返回 true
     *
     * @param s
     * @return
     * @author Robin Chang
     */
    public static boolean isEmpty(String s) {
        if (s != null && !s.equals("")) {
            return false;
        }
        return true;
    }

    /**
     * 判断字符串是否为空白
     */
    public static boolean isBlank(String str) {
        return str == null || str.trim().isEmpty();
    }

    /**
     * 判断对象是否为空
     *
     * @param str
     * @return
     */
    public static boolean isNotEmpty(Object str) {
        boolean flag = true;
        if (str != null && !str.equals("")) {
            if (str.toString().length() > 0) {
                flag = true;
            }
        } else {
            flag = false;
        }
        return flag;
    }

    /**
     * 生成福利模板编号
     *
     * @param prefix
     * @param data
     * @return
     */
    public static String getNumber(String prefix, String data) {
        return getNumber(prefix, data, LEN2);
    }

    public static String getNumber(String prefix, String data, int num) {
        String ix = String.valueOf(data);
        if (ix.length() < num) {
            int l = num - ix.length();
            for (int i = 0; i < l; i++) {
                ix = "0" + ix;
            }
        }
        return prefix + ix;
    }

    /**
     * 判断是否为数字
     *
     * @param str
     * @return
     */
    public static boolean isNumer(String str) {
        Pattern pattern = Pattern.compile("-?[0-9]+(\\.[0-9]+)?");
        Matcher isNum = pattern.matcher(str);
        if ("0".equals(str)) {
            return true;
        }
        if (!isNum.matches()) {
            return false;
        }
        return true;
    }

    /**
     * 日期转换为字符串
     *
     * @param date   日期
     * @param format 日期格式
     * @return 指定格式的日期字符串
     */
    public static String parseDateStr(Date date, String format) {
        String result = "";
        if (date != null) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(format);
                result = sdf.format(date);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 日期格式字符串转换为日期对象
     *
     * @param strDate 日期格式字符串
     * @param pattern 日期对象
     * @return
     */
    public static Date parseDate(String strDate, String pattern) {
        try {
            SimpleDateFormat format = new SimpleDateFormat(pattern);
            Date nowDate = format.parse(strDate);
            return nowDate;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 得到当前日期字符串
     *
     * @return
     */
    public static String getNowDateStr() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        return simpleDateFormat.format(new Date());
    }

    /**
     * 创建文件,如果文件名重复则自动更改文件名
     *
     * @param path     文件路径
     * @param fileName 文件名
     * @param count    默认传入初始次数 2
     * @return 返回新创建的文件
     * @throws Exception
     */
    public static File getFileByOriginalFileName(String path, String fileName, int count) throws Exception {
        File targetFile = new File(path, fileName);

        if (!targetFile.exists()) {
            targetFile.mkdirs();
        } else {
            String new_fileName = fileName.substring(0, fileName.lastIndexOf("."));

            if (count != 2) {
                new_fileName = fileName.substring(0, fileName.lastIndexOf("(" + (count - 1) + ")"));
            }

            new_fileName += "(" + count + ")";

            //加入文件后缀
            if (fileName != null && !"".equals(fileName) && fileName.lastIndexOf(".") != -1) {
                new_fileName += fileName.substring(fileName.lastIndexOf("."), fileName.length()).toLowerCase();
            }
            count++;
            //递归，调用自身
            targetFile = getFileByOriginalFileName(path, new_fileName, count);
        }
        return targetFile;
    }

    /***
     * 生成二维码
     * @param content 二维码里面的内容
     */
    public static BufferedImage createImages(String content) throws Exception {
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
        hints.put(EncodeHintType.MARGIN, 1);
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, 260, 260, hints);
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
            }
        }
        return image;
    }


    //java画图时切割字符串，font就一行显示多少字=控件宽度/字体大小-首尾空格（width/fontSize - 2）
    public static List<String> dealRows(String text, int font) {
        text = text.trim();
        StringBuffer sb = new StringBuffer();
        List<String> list = new ArrayList<String>();
        int tmp = 0;
        int row = 0;
        int fontSize = font * 2;
        int fontStrSize = 0;
        for (char c : text.toCharArray()) {
            tmp = isChinese(c) ? 2 : 1;
            fontStrSize = fontStrSize + tmp;
            sb.append(c);
            if (fontSize <= fontStrSize) {
                fontStrSize = 0;
                list.add(sb.toString());
                sb = new StringBuffer();
                row++;
            }
        }
        if (row == 0 || fontStrSize < fontSize) {
            list.add(sb.toString());
        }
        return list;
    }

    //  GENERAL_PUNCTUATION 判断中文的“号
    //  CJK_SYMBOLS_AND_PUNCTUATION 判断中文的。号
    //  HALFWIDTH_AND_FULLWIDTH_FORMS 判断中文的，号
    public static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
            return true;
        }
        return false;
    }

}
